package ccm.itesm.mx.servicios;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

//Extiende ListActivity para que podamos modificar una ListView
//Implementa Runnable para el uso de threads para que el ProgressDialog funcione bien
public class FaltasActivity extends ListActivity implements Runnable {
	
	private AndroidDAO dao;
	//VARIABLES INICIALES
	//El ProgressDialog es el mensajito usado que dice "Cargando Faltas"
	ProgressDialog cargandoFaltas;
	//Los Strings necesarios para llamar al JSON y cargar la info
	static String materias = "http://escolares.ccm.itesm.mx/~mobile/boleta/boleta.php?mat=";
	static String cursos = "http://escolares.ccm.itesm.mx/~mobile/boleta/grupos.php?crs=";
	static String periodo = "&trm=201113";
	
	//Los ArrayLists para meter la info cargada desde el JSON
	//Y una List para meter la info de las ArrayLists en el adaptador
	private ArrayList<String> listaCRNs, listaMaterias;
	private ArrayList<Integer> listaFaltas;
	private List<ColumnasDatos> listaFaltaDatos = new ArrayList<ColumnasDatos>();
	
	//El onCreate (Right-click -> Source -> Override/Implement Methods... -> onCreate(Bundle)
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		//Hay que ponerle el Content View correspondiente, en este caso es el --- faltas.xml ---
		setContentView(R.layout.faltas);
		
		//El ProgressDialog (mensajito) que muestra como titulo "Cargando Faltas" y como subtexto "Espera un momento..."
		cargandoFaltas = ProgressDialog.show(this, "Cargando Faltas", "Espera un momento...", true, false);
		
        //Empezamos nuestro Thread cargarInfo, que se carga la info del JSON mientras el ProgressDialog se muestra
		Thread cargarInfo = new Thread(this);
		cargarInfo.start();
	}
	
	public void run() {
		//Se toma el bundle recibido del Intent, en esta caso contenia la Matricula
		final Bundle bundle = this.getIntent().getExtras();
        
        //Inicializamos las ArrayLists
    	listaCRNs = new ArrayList<String>();
    	listaMaterias = new ArrayList<String>();
    	listaFaltas = new ArrayList<Integer>();
    	
    	//Mandamos llamar el metodo cargaMaterias y le mandamos la matricula
    	//cargaMaterias(bundle.getString("matricula"));
    	this.dao = new AndroidDAO(this);
    	List<String> db = dao.selectAll();
    	
    	cargaMaterias(db.get(0));
    	
    	dao.open.close();
    	
    	//Ya que las ArrayLists contienen la info del JSON, la ingresamos en listaFaltaDatos para poder usar nuestro adaptador
    	for(int i=0; i<listaMaterias.size(); i++) {
    		listaFaltaDatos.add(new ColumnasDatos(listaMaterias.get(i), listaFaltas.get(i).toString()));
    	}
    	
    	//Con un Handler se controla el Thread y se carga la info a nuestro respectivo Layout
    	manejador.sendEmptyMessage(0);
	}
	
	private Handler manejador = new Handler() {
		//El handleMessage (Right-click -> Source -> Override/Implement Methods... -> handleMessage(Message)
		@Override
		public void handleMessage(Message msg) {
			//Cuando el Thread acaba, usamos nuestro adaptador para poner nuestra info en el Layout
			//Hay que especificar FaltasActivity.this como el Content y mandarle nuestra List
			setListAdapter(new ColumnasAdaptador(FaltasActivity.this, listaFaltaDatos));
			
			//Ya que cargo toda la info, quitamos nuestro ProgressDialog
			cargandoFaltas.dismiss();
		}
	};
	
    //AQUI EMPIEZAN LOS METODOS PARA CARGAR LA INFO DEL JSON
	//cargaMaterias mete nuestras faltas en listaFaltas y los crn en listaCRNs
	private void cargaMaterias(String matricula){
		//Crea la consulta completa para las materias
		String consulta = materias + matricula.trim() + periodo;
		
		//Llama a download para el uso de la info del JSON
		String dlAnswer = download(consulta);
		
		if(dlAnswer != null && !dlAnswer.startsWith("Error")) {
			try {
				//Crea un JSONArray que contiene todas las materias con la dlAnswer
				JSONArray materias = new JSONArray(dlAnswer);
				
				//Toast.makeText(FaltasActivity.this.getApplicationContext(), ""+materias.length(), Toast.LENGTH_LONG).show();
				if(materias.length()>0){
					for(int i=0; i<materias.length(); i++){
						//Crea un JSONObject del JSONArray para manejar una materia en especifico
						JSONObject consultaMateria = materias.getJSONObject(i);
						//Agrega el CRN de esta materia a listaCRNs
						listaCRNs.add(consultaMateria.getString("crn"));
						//Suma y agrega las faltas
						listaFaltas.add(consultaMateria.getInt("falt_it") +
										consultaMateria.getInt("falt_p1") +
										consultaMateria.getInt("falt_p2") +
										consultaMateria.getInt("falt_p3") +
										consultaMateria.getInt("falt_p4"));
					}
					
					//Con los CRN que tenemos en listaClaves, cargamos el nombre de cada materia
					cargaNombresMaterias(listaCRNs);
				} else {
					//Si no hay ninguna materia, tostea que "No hay datos"
					Toast.makeText(getBaseContext(), "No hay datos", Toast.LENGTH_LONG).show();
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
	}
	
	//cargaNombresMaterias nos regresa el nombre de cada materia a partir del CRN
	private void cargaNombresMaterias(ArrayList<String> listaCRNs) {
		//Crea las variables consulta y dlAnswer
		String consulta, dlAnswer;
		
		//Para cada crn, hace una consulta para conseguir el nombre de la materia
		for(int j=0; j<listaCRNs.size(); j++) {
			consulta = cursos + listaCRNs.get(j) + periodo;
			dlAnswer = download(consulta);
			
			if(dlAnswer != null && !dlAnswer.startsWith("Error")) {
				try {
					//Crea un JSONArray con la dlAnswer y mete los nombres a listaMaterias
					JSONArray nombreMaterias = new JSONArray(dlAnswer);
					if(nombreMaterias.length() > 0) {
						for(int i=0; i<1; i++) {
							JSONObject consultaNombreMateria = nombreMaterias.getJSONObject(i);
							this.listaMaterias.add(consultaNombreMateria.getString("nommat"));
						}
					} else {
						//Si no hay ninguna materia, tostea que "No hay datos"
						Toast.makeText(getBaseContext(), "No hay datos", Toast.LENGTH_LONG).show();
					}
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	private String download(String consulta) {
		//Variables para hacer la conexion
		InputStream is = null;
        byte[] data = null;
        URLConnection connection = null;
        
        //Trata de establecer la conexion
        try {
        	URL url = new URL(consulta);
	    	connection = url.openConnection();
	    	
	    	if ((connection instanceof HttpURLConnection)) {
	    		//Cambia la conexion a HttpUrlConnection
	    		HttpURLConnection httpConnection = (HttpURLConnection) connection;
	    		
	    		httpConnection.setAllowUserInteraction(false);
	    		httpConnection.setInstanceFollowRedirects(true);
	    		httpConnection.setRequestMethod("GET");
	    		httpConnection.connect();
	    		
	    		if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
	    			is = httpConnection.getInputStream();
	    			ByteArrayOutputStream baos = new ByteArrayOutputStream();
	    			int c;
	    			while((c = is.read()) > -1)
	                    baos.write(c);
	    			data = baos.toByteArray();
	                baos.close();
	                is.close();
	                String string = new String(data);
	                return string;
	    		} else {
	    			return("Error reading data");
	    		}
	    	}
        } catch (Exception e) {
        	return("Error in connection");
        } finally {
        	try {
        		if(connection != null) {
        			connection = null;
        		}
        		if(is != null) {
        			is.close();
        			is = null;
        		}
        	} catch(IOException ioe) {
        		return("Error: " + ioe.getMessage());
        	}
        }
        return null;
	}
}